<!-- eslint-disable vue/valid-attribute-name -->
<template>
  <div>
    <el-card>
      <el-form :inline="true" class="form" style="height: 30px">
        <el-form-item label="职位搜索">
          <el-input v-model="keyword" placeholder="请输入职位关键字"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="search">搜索</el-button>
          <el-button type="default" @click="reset">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>
    <el-card style="margin: 10px 0px">
      <!-- 操作职位信息 -->
      <el-form>
        <el-form-item>
          <el-button @click="addRole" type="primary" icon="Plus">
            添加职位
          </el-button>
        </el-form-item>
      </el-form>
      <!-- 表格展示职位信息 -->
      <el-table border style="margin: 10px 0px" :data="allRole">
        <el-table-column
          label="#"
          align="center"
          type="index"
        ></el-table-column>
        <el-table-column label="id" align="center" prop="id"></el-table-column>
        <el-table-column
          label="职位名称"
          prop="roleName"
          align="center"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column
          label="创建时间"
          prop="createTime"
          align="center"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column
          label="更新时间"
          prop="updateTime"
          align="center"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column label="操作" align="center" width="280px">
          <template #="{ row }">
            <el-button
              @click="setPermisstion(row)"
              size="small"
              type="primary"
              icon="User"
            >
              分配权限
            </el-button>
            <el-button
              @click="updateRole(row)"
              size="small"
              type="primary"
              icon="Edit"
            >
              编辑
            </el-button>
            <!-- 气泡确认框 -->
            <el-popconfirm
              :title="`你确定要删除${row.roleName}吗？`"
              width="250px"
              @confirm="removeRole(row.id)"
            >
              <template #reference>
                <el-button size="small" type="danger" icon="Delete">
                  删除
                </el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页器组件 -->
      <el-pagination
        @current-change="getHasRole"
        @size-change="sizeChange"
        v-model:current-page="pageNo"
        v-model:page-size="limit"
        :page-sizes="[10, 20, 30, 40]"
        :background="true"
        :small="false"
        layout=" prev, pager, next, jumper,->, sizes,total"
        :total="total"
      />
    </el-card>
    <!-- 添加或者更新职位的对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="RoleParams.id ? '更新职位' : '添加职位'"
    >
      <el-form :model="RoleParams" :rules="rules" ref="form">
        <el-form-item label="职位名称" prop="roleName">
          <el-input
            placeholder="请输入职位名称"
            v-model="RoleParams.roleName"
          ></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="save">确定</el-button>
      </template>
    </el-dialog>
    <!-- 抽屉组件:分配权限 -->
    <el-drawer v-model="drawer">
      <template #header>
        <h4>分配权限</h4>
      </template>
      <template #default>
        <!-- 树形组件 -->
        <el-tree
          ref="tree"
          :data="menuArr"
          show-checkbox
          node-key="id"
          default-expand-all
          :default-checked-keys="selectArr"
          :props="defaultProps"
        />
      </template>
      <template #footer>
        <div style="flex: auto">
          <el-button @click="drawer = false">取消</el-button>
          <el-button @click="handler" type="primary">确定</el-button>
        </div>
      </template>
    </el-drawer>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, reactive, nextTick } from 'vue'
// 引入请求API
import {
  reqAllRoleList,
  reqAddOrUpdateRole,
  reqAllMenuList,
  reqSetPermisstion,
  reqRemoveRole,
} from '../../../api/acl/role/'
// 引入ts类型
import type {
  RoleResponseData,
  Records,
  RoleData,
  MenuList,
  MenuResponseData,
} from '../../../api/acl/role/type'
import { ElMessage } from 'element-plus'
// 分页器默认页码
let pageNo = ref<number>(1)
// 一页展示多少个数据
let limit = ref<number>(10)
// 职位总个数
let total = ref<number>(40)
// 搜索职位的关键字
let keyword = ref<string>('')
// 存储当前获取的全部职位
let allRole = ref<Records>([])
// 控制对话框的显示与隐藏
let dialogVisible = ref<boolean>(false)
// 控制抽屉的显示与隐藏
let drawer = ref<boolean>(false)
// 收集新增职位的数据
let RoleParams = reactive<RoleData>({
  roleName: '',
})
// 获取表单的实例
let form = ref<any>()
// 收集分配权限的数据
let menuArr = ref<MenuList>([])
// 准备一个数组:由于存储勾选项的ID
let selectArr = ref<number[]>([])
// 获取tree组件的实例
let tree = ref<any>()

// 组件挂载完毕
onMounted(() => {
  // 获取全部职位的请求
  getHasRole()
})
// 封装一个获取全部职位信息的方法
const getHasRole = async (page = 1) => {
  // 修改页码——默认是1
  pageNo.value = page
  // 请求API
  const result: RoleResponseData = await reqAllRoleList(
    pageNo.value,
    limit.value,
    keyword.value,
  )
  if (result.code == 200) {
    // 存储数据
    total.value = result.data.total
    allRole.value = result.data.records
  }
}
// 分页器下拉菜单发生变化的时候触发
const sizeChange = () => {
  getHasRole()
}
// 搜索按钮的回调
const search = () => {
  getHasRole()
  // 清空记录
  keyword.value = ''
}
// 重置按钮的回调
const reset = () => {
  // 利用window自带的方法刷新  也可以使用setting仓库中的refresh方法刷新
  window.location.reload()
}
// 添加职位按钮的回调
const addRole = () => {
  // 显示对话框
  dialogVisible.value = true
  // 清空记录
  Object.assign(RoleParams, {
    roleName: '',
    id: 0,
  })
  // 请空错误提示
  nextTick(() => {
    form.value.clearValidate('roleName')
  })
}
// 更新职位按钮的回调
const updateRole = (row: RoleData) => {
  // 显示对话框
  dialogVisible.value = true
  // 请空错误提示
  nextTick(() => {
    form.value.clearValidate('roleName')
  })
  // 替换存储职位数据
  Object.assign(RoleParams, row)
}
// 校验roleName的回调
const validatorRoleName = (_rule: any, value: any, callback: any) => {
  if (value.trim().length >= 2) {
    callback()
  } else {
    callback(new Error('职位至少要两位'))
  }
}
// 职位检验规则
const rules = {
  roleName: [{ required: true, trigger: 'blur', validator: validatorRoleName }],
}
// 添加|更新职位的确定按钮的回调
const save = async () => {
  // 在发请求前要先表单校验全部通过
  await form.value.validate()
  // 要是校验通过了就发请求
  const result: any = await reqAddOrUpdateRole(RoleParams)
  if (result.code == 200) {
    ElMessage({
      type: 'success',
      message: RoleParams.id ? '更新职位成功' : '添加职位成功',
    })
    // 关闭对话框
    dialogVisible.value = false
    // 再次发请求获取数据
    getHasRole(RoleParams.id ? pageNo.value : 1)
  } else {
    ElMessage({
      type: 'error',
      message: RoleParams.id ? '更新职位失败' : '添加职位失败',
    })
  }
}
// 分配权限按钮的回调
const setPermisstion = async (row: RoleData) => {
  // 显示抽屉
  drawer.value = true
  // 存储已有职位的数据
  Object.assign(RoleParams, row)
  // 根据已有职位的id获取权限数据
  const result: MenuResponseData = await reqAllMenuList(RoleParams.id as number)
  if (result.code == 200) {
    // 存储数据给权限数组
    menuArr.value = result.data
    selectArr.value = filterSelectArr(menuArr.value, [])
  } else {
    ElMessage({
      type: 'error',
      message: '获取权限数据失败',
    })
  }
}
// 树形组件展示数据的规则
const defaultProps = {
  children: 'children',
  // 展示的数据
  label: 'name',
}
// 过滤已勾选项的方法
const filterSelectArr = (allData: any, initArr: any) => {
  allData.forEach((item: any) => {
    if (item.select && item.level == 4) {
      initArr.push(item.id)
    }
    if (item.children && item.children.length > 0) {
      // 递归
      filterSelectArr(item.children, initArr)
    }
  })
  return initArr
}
// 抽屉确定按钮的回调
const handler = async () => {
  // 职位的ID
  const roleId = RoleParams.id
  // 选中节点的ID
  let arr = tree.value.getCheckedKeys()
  // 半选中节点的ID
  let arr1 = tree.value.getHalfCheckedKeys()
  // 合并选中节点ID
  let permissionId = arr.concat(arr1)
  // 发送请求，分配权限
  const result: any = await reqSetPermisstion(roleId as number, permissionId)
  if (result.code == 200) {
    // 关闭抽屉
    drawer.value = false
    // 提示信息
    ElMessage({
      type: 'success',
      message: '分配权限成功',
    })
    // 重新刷新一下页面
    window.location.reload()
  } else {
    ElMessage({
      type: 'error',
      message: '分配权限失败',
    })
  }
}
// 确定删除已有职位的回调
const removeRole = async (roleId: number) => {
  // 更新对应roleId删除对应职位数据
  const result: any = await reqRemoveRole(roleId)
  if (result.code == 200) {
    ElMessage({
      type: 'success',
      message: '删除职位成功',
    })
    // 重新获取职位信息
    getHasRole(allRole.value.length > 1 ? pageNo.value : pageNo.value - 1)
  } else {
    ElMessage({
      type: 'error',
      message: '删除职位失败',
    })
  }
}
</script>

<style scoped>
.form {
  display: flex;
  justify-content: space-between;
}
</style>
